#region License

/*
  GShield - Game Shield
  Copyright (C) 2006-2007 WaveTech Digital Technologies, Inc.
                                http://www.wtdt.com

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#endregion License

#region Includes

using System;
using System.Linq;
using WaveTech.GShield.Data.Collections;

#endregion

namespace WaveTech.GShield.Data
{
	public static class UsageLogsDAO
	{
		#region Get Usage Log For Process By Day

		public static UsageLog GetUsageLogForProcessByDay(DateTime? day, string userName, int? gameId)
		{
			var log = from l in Database.DC.UsageLogs
			          where l.Username == userName && l.ParentId == gameId && l.Timestamp.Value.Day == day.Value.Day
			          select l;

			return log.Single();
		}

		#endregion Get Usage Logs For User By Day

		#region Get Usage Log For Day

		public static UsageLogsCollection GetUsageLogsForUserByDay(DateTime? day, string userName)
		{
			var log = from l in Database.DC.UsageLogs
			          where l.Username == userName && l.Timestamp.Value.Day == day.Value.Day
			          select l;

			return (UsageLogsCollection) log.ToList();
		}

		#endregion Get Usage Logs For User By Day

		#region Save

		public static void Save(UsageLog log)
		{
			Database.DC.UsageLogs.InsertOnSubmit(log);
			Database.DC.SubmitChanges();
		}

		#endregion Save
	}

	#region Old UsageLogsDAO

	/*
	/// <summary>
	/// Usage Logging Data Access Objects
	/// </summary>
	public class UsageLogsDAO
	{
		#region Save
		/// <summary>
		/// Saves or Updates a Log entry into the database.
		/// </summary>
		/// <param name="log">Populated Log Object</param>
		/// <returns>Populated Log Object of Persisted Data</returns>
		public Log Save(Log log)
		{
			if (log == null)
				throw new ArgumentNullException("log");

			Log m_log;

			if (log.Id == null)
				m_log = Insert(log);
			else
				m_log = Update(log);

			return m_log;
		}
		#endregion Save

		#region Insert
		/// <summary>
		/// Inserts a new Log object to the database
		/// </summary>
		/// <param name="log">Log object to save</param>
		/// <returns>Populated Log object with it's new Id</returns>
		private Log Insert(Log log)
		{
			if (log == null)
				throw new ArgumentNullException("log");
			else if (log.Id != null)
				throw new ArgumentException("Log.Id must be null to perform an insert.");

			Database db;
			DbCommand dbCommand;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"	INSERT INTO [UsageLogs]
																						([Type] ,[ParentId] ,[UserName] ,[Time] ,[TimeType] ,[Message] ,[Timestamp] ,[Hash])
																	VALUES		(@Type ,@ParentId ,@UserName ,@Time ,@TimeType ,@Message ,@Timestamp ,@Hash)
																						SELECT @Id = Scope_Identity()");

			db.AddInParameter(dbCommand, "@Type", DbType.Int32, (int)log.LogType);
			db.AddInParameter(dbCommand, "@ParentId", DbType.Int32, log.ParentId);
			db.AddInParameter(dbCommand, "@UserName", DbType.String, log.UserName);
			db.AddInParameter(dbCommand, "@Time", DbType.Int32, log.Time);
			db.AddInParameter(dbCommand, "@TimeType", DbType.Int32, log.TimeType);
			db.AddInParameter(dbCommand, "@Message", DbType.String, log.Message);
			db.AddInParameter(dbCommand, "@Timestamp", DbType.DateTime, log.Timestamp);
			db.AddInParameter(dbCommand, "@Hash", DbType.String, log.ComputeHash());

			db.AddOutParameter(dbCommand, "@Id", DbType.Int32, 9);

			db.ExecuteNonQuery(dbCommand);

			if (db.GetParameterValue(dbCommand, "@Id") != DBNull.Value)
				log.Id = int.Parse(db.GetParameterValue(dbCommand, "@Id").ToString());

			return log;
		}
		#endregion Insert

		#region Update
		/// <summary>
		/// Updates an existing log object in the database
		/// </summary>
		/// <param name="log">Updated log object</param>
		/// <returns>Copy of the persisted Log object</returns>
		private Log Update(Log log)
		{
			if (log == null)
				throw new ArgumentNullException("log");
			else if (log.Id == null)
				throw new ArgumentException("Log.Id must be not null to perform an update.");

			Database db;
			DbCommand dbCommand;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"UPDATE [UsageLogs]
																					SET [Type] = @Type ,[ParentId] = @ParentId ,[UserName] = @UserName ,[Time] = @Time
																						 ,[TimeType] = @TimeType ,[Message] = @Message ,[Timestamp] = @Timestamp ,[Hash] = @Hash
																					WHERE (Id = @Id)");

			db.AddInParameter(dbCommand, "@Id", DbType.String, log.Id);
			db.AddInParameter(dbCommand, "@Type", DbType.String, log.LogType);
			db.AddInParameter(dbCommand, "@ParentId", DbType.String, log.ParentId);
			db.AddInParameter(dbCommand, "@UserName", DbType.String, log.UserName);
			db.AddInParameter(dbCommand, "@Time", DbType.String, log.Time);
			db.AddInParameter(dbCommand, "@TimeType", DbType.Int32, log.TimeType);
			db.AddInParameter(dbCommand, "@Message", DbType.String, log.Message);
			db.AddInParameter(dbCommand, "@Timestamp", DbType.String, log.Timestamp);
			db.AddInParameter(dbCommand, "@Hash", DbType.String, log.ComputeHash());

			db.ExecuteNonQuery(dbCommand);

			return log;
		}
		#endregion Update

		#region Get
		/// <summary>
		/// Gets a Log object from the database by it's Id.
		/// </summary>
		/// <param name="id">Id number of the Log to retreive</param>
		/// <returns>Populated Log object</returns>
		public Log Get(int? id)
		{
			if (id == null)
				throw new ArgumentNullException("id");

			Database db;
			DbCommand dbCommand;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"SELECT [Id], [Type], [ParentId], [UserName], [Time], 
																									[TimeType], [Message], [Timestamp], [Hash]
																					FROM [UsageLogs]
																					WHERE (Id = @Id)");

			db.AddInParameter(dbCommand, "@Id", DbType.Int32, id);

			return FillLog(db.ExecuteReader(dbCommand));
		}

		/// <summary>
		/// Retrives all the Logs from the database
		/// </summary>
		/// <returns>Filled Log Collection of Logs</returns>
		public LogsCollection Get()
		{
			Database db;
			DbCommand dbCommand;
			IDataReader reader;
			LogsCollection logs = null;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"SELECT [Id], [Type], [ParentId], [UserName], 
																									[Time], [TimeType], [Message], [Timestamp], [Hash]
																					FROM [UsageLogs]");

			reader = db.ExecuteReader(dbCommand);

			if (reader != null)
			{
				logs = new LogsCollection();
				Log m_log = FillLog(reader);

				while (m_log != null)
				{
					logs.Add(m_log);
					m_log = FillLog(reader);
				}
			}

			return logs;
		}
		#endregion Get Logs

		#region Clear
		/// <summary>
		/// Clears all the logs from the database.
		/// </summary>
		public void Clear()
		{
			Database db;
			DbCommand dbCommand;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand("DELETE FROM [UsageLogs]");

			db.ExecuteNonQuery(dbCommand);
		}
		#endregion Clear

		#region Get Usage Log For Process By Day
		/// <summary>
		/// Gets the Usage Logs for a Process by a given day
		/// </summary>
		/// <param name="day">Day to retrieve the logs for</param>
		/// <param name="userName">User Name to retreives the logs for</param>
		/// <param name="gameId">GameId of the game to retreive log for</param>
		/// <returns>Populated Log Object</returns>
		public Log GetUsageLogForProcessByDay(DateTime? day, string userName, int? gameId)
		{
			if (day == null)
				throw new ArgumentNullException("day");
			else if (userName == null || userName.Length <= 0)
				throw new ArgumentNullException("username");
			else if (gameId == null)
				throw new ArgumentNullException("gameId");

			Database db;
			DbCommand dbCommand;
			Log l;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"SELECT [Id], [Type], [ParentId], [UserName], 
																									[Time], [TimeType], [Message], [Timestamp], [Hash]
																					 FROM [UsageLogs]
																					 WHERE (Type = 2) AND (UserName = @UserName) AND ([ParentId] = @GameId) AND 
																									(CONVERT(CHAR(8),[Timestamp],112) = CONVERT(CHAR(8),@Day,112))");

			db.AddInParameter(dbCommand, "@GameId", DbType.Int32, gameId);
			db.AddInParameter(dbCommand, "@UserName", DbType.String, userName);
			db.AddInParameter(dbCommand, "@Day", DbType.DateTime, day);

			l = FillLog(db.ExecuteReader(dbCommand));

			return l;
		}
		#endregion Get Usage Log For Process By Day

		#region Get Useage Logs
		/// <summary>
		/// Gets the Useage logs for a specific user
		/// </summary>
		/// <param name="userName">User name to retreive logs for</param>
		/// <returns>Filled Collection of Logs</returns>
		public LogsCollection GetUsageLogs(string userName)
		{
			if (userName == null || userName.Length <= 0)
				throw new ArgumentNullException("userName");

			Database db;
			DbCommand dbCommand;
			IDataReader reader;
			LogsCollection logs = null;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"SELECT [Id], [Type], [ParentId], [UserName], [Time], 
																									[TimeType], [Message], [Timestamp], [Hash]
																					 FROM [UsageLogs]
																					 WHERE (UserName = @UserName)");

			db.AddInParameter(dbCommand, "@UserName", DbType.String, userName);

			reader = db.ExecuteReader(dbCommand);

			if (reader != null)
			{
				logs = new LogsCollection();
				Log m_log = FillLog(reader);

				while (m_log != null)
				{
					logs.Add(m_log);
					m_log = FillLog(reader);
				}
			}

			return logs;
		}
		#endregion Get Useage Logs

		#region Get Useage Logs For Day
		/// <summary>
		/// Gets all the usage logs for a specific day and user
		/// </summary>
		/// <param name="day">Day to retreive the logs for</param>
		/// <param name="userName">User name to retrieve the logs for</param>
		/// <returns>Filled Collection of Logs</returns>
		public LogsCollection GetUsageLogsForDay(DateTime? day, string userName)
		{
			if (day == null)
				throw new ArgumentNullException("day");
			else if (userName == null || userName.Length <= 0)
				throw new ArgumentNullException("userName");

			Database db;
			DbCommand dbCommand;
			IDataReader reader;
			LogsCollection logs = null;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"SELECT [Id], [Type], [ParentId], [UserName], [Time], 
																								  [TimeType], [Message], [Timestamp], [Hash]
																					FROM [UsageLogs]
																					WHERE (UserName = @UserName) AND (CONVERT(CHAR(8),[Timestamp],112) = CONVERT(CHAR(8),@Day,112))");

			db.AddInParameter(dbCommand, "@UserName", DbType.String, userName);
			db.AddInParameter(dbCommand, "@Day", DbType.DateTime, day);

			reader = db.ExecuteReader(dbCommand);

			if (reader != null)
			{
				logs = new LogsCollection();
				Log m_log = FillLog(reader);

				while (m_log != null)
				{
					logs.Add(m_log);
					m_log = FillLog(reader);
				}
			}

			return logs;
		}
		#endregion Get Useage Logs For Day

		#region Fill Log
		private Log FillLog(IDataReader reader)
		{
			if (reader == null)
				throw new ArgumentNullException("reader");

			Log l = null;

			if (reader.Read())
			{
				l = new Log();

				if (!reader.IsDBNull(reader.GetOrdinal("Id")))
					l.Id = reader.GetInt32(reader.GetOrdinal("Id"));

				if (!reader.IsDBNull(reader.GetOrdinal("Type")))
					l.LogType = (LogType)reader.GetInt32(reader.GetOrdinal("Type"));

				if (!reader.IsDBNull(reader.GetOrdinal("ParentId")))
					l.ParentId = reader.GetInt32(reader.GetOrdinal("ParentId"));

				if (!reader.IsDBNull(reader.GetOrdinal("UserName")))
					l.UserName = reader.GetString(reader.GetOrdinal("UserName"));

				if (!reader.IsDBNull(reader.GetOrdinal("Time")))
					l.Time = reader.GetInt32(reader.GetOrdinal("Time"));

				if (!reader.IsDBNull(reader.GetOrdinal("TimeType")))
					l.TimeType = (TimeType)reader.GetInt32(reader.GetOrdinal("TimeType"));

				if (!reader.IsDBNull(reader.GetOrdinal("Message")))
					l.Message = reader.GetString(reader.GetOrdinal("Message"));

				if (!reader.IsDBNull(reader.GetOrdinal("Timestamp")))
					l.Timestamp = reader.GetDateTime(reader.GetOrdinal("Timestamp"));

				if (!reader.IsDBNull(reader.GetOrdinal("Hash")))
					l.Hash = reader.GetString(reader.GetOrdinal("Hash"));
			}
			return l;
		}
		#endregion Fill Log
	}
    */

	#endregion Old UsageLogsDAO
}